/**
 * Created by 艺 on 16/10/09.
 */
import { memoize } from 'lodash'

export function getLocal(key, defaultVal) {
  let item = JSON.parse(localStorage.getItem(key))
  return item || (defaultVal !== undefined ? defaultVal : item)
}

// localStorage 往数组添加元素
export function addLocal(key, value, maxLen) {
  let item = JSON.parse(localStorage.getItem(key)) || []
  item.unshift(value)
  if (maxLen) {
    item.splice(maxLen)
  }
  localStorage.setItem(key, JSON.stringify(item))
  return item
}

// 检测相似度, Levenshtein Distance
let toCharArr = memoize(str => {
  return str.split('')
})
function minConvStep(s1 = '', s2 = '') {
  let charArr = [s1, s2].map(toCharArr), arr = []
  for (let i = 0; i <= charArr[0].length; i++) {
    arr[i] = []
    for (let j = 0; j <= charArr[1].length; j++) {
      if (i * j == 0) {
        arr[i][j] = j + i
      } else {
        arr[i][j] = Math.min(arr[i - 1][j - 1] + (charArr[0][i - 1] == charArr[1][j - 1] ? 0 : 1),
          arr[i - 1][j] + 1, arr[i][j - 1] + 1)
      }
    }
  }
  return arr[charArr[0].length][charArr[1].length]
}
export let calcSimilarity = memoize((s1 = '', s2 = '') => {
  return 1 - minConvStep(s1, s2) / Math.max(1, s1.length, s2.length)
}, (s1 = '', s2 = '') => s1 > s2 ? s1 + s2 : s2 + s1)

// java string hashcode的js实现
export function hashCode(str) {
  let hash = 0
  if (str.length == 0) return hash
  for (let i = 0; i < str.length; i++) {
    let char = str.charCodeAt(i)
    hash = ((hash << 5) - hash) + char
    hash = hash & hash // Convert to 32bit integer
  }
  return hash
}

export class MessageRouter {
  constructor() {
    this.routes = {}
    this.addListener((message, ...restArgs) => {
      if (!this.filterMessage || this.filterMessage.call(this, message)) {
        let route = message.route, items = this.routes[route]
        if (items) {
          items.forEach(item => {
            if (typeof item === 'function') {
              item.apply(this, [message.data, message, ...restArgs])
            }
          })
        } else {
        }
      } else {
        return true
      }
    })
  }

  addListener(cb) {
    chrome.runtime.onMessage.addListener(cb)
  }

  filterMessage(message) {
    return !!message.route
  }

  register(routes, prefix = '') {
    for (let route in routes) {
      let path = prefix + route,
          item = routes[route]
      switch (typeof item) {
        case 'function':
          let currItems = (this.routes[path] || (this.routes[path] = []))
          currItems.push(item)
          break
        case 'object':
          this.register(item, path + '/')
          break
        default:
          console.warn(`what's this : ${path}, ${item}`)
          break
      }
    }
  }
}